package com.example.demo.jwt;


import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import net.sf.json.JSONObject;
import java.util.HashMap;
import java.util.Map;

public class Jwt {


    /**
     * 秘钥
     */
    private static final byte[] SECRET="linbin".getBytes();

    /**
     * 生成token，该方法只在用户登录成功后调用
     * @param payload 可以存储用户id，token生成时间，token过期时间等自定义字段
     * @return token字符串,若失败则返回null
     */
    public static String createToken(JSONObject payload) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");

        String token = JWT.create()
                .withHeader(map)//header
                .withClaim("info", payload.toString())//payload
//                .withExpiresAt(expiresDate)//设置过期时间
//                .withIssuedAt(iatDate)//设置签发时间
                .sign(Algorithm.HMAC256(SECRET));//加密
        return token;
    }

    /**
     * 校验token是否合法，返回Map集合,集合中主要包含    state状态码   data鉴权成功后从token中提取的数据
     * 该方法在过滤器中调用，每次请求API时都校验
     * @param token
     * @return  Map<String, Object>
     */
    public static JSONObject validToken(String token) {
        JSONObject result = new JSONObject();
        try {

            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET))
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            Map<String, Claim> claims = jwt.getClaims();

            JSONObject jsonOBj=JSONObject.fromObject(claims.get("info").asString());

            // 若payload包含ext字段，则校验是否过期
            if (jsonOBj.containsKey("ext")) {
                long extTime = Long.valueOf(jsonOBj.get("ext").toString());
                long curTime = System.currentTimeMillis();
                // 过期了
                if (curTime > extTime) {
                    result.clear();
                    result.put("state", TokenState.EXPIRED.toString());
                }else{
                    // token校验成功（此时没有校验是否过期）
                    result.put("state", TokenState.VALID.toString());
                }
            }
            result.put("data", jsonOBj);
        } catch (Exception e) {
            result.clear();
            result.put("state", TokenState.INVALID.toString());
        }
        return result;
    }

}
